import pymysql
import requests
import time
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry

DB_CONFIG = {
    "host": "localhost",
    "user": "root",
    "password": "1234",
    "database": "project_exam",
    "charset": "utf8mb4"
}

# —— 1. 获取所有占位符条目 —— #
def fetch_placeholders():
    conn = pymysql.connect(**DB_CONFIG)
    cur = conn.cursor()
    cur.execute("""
        SELECT content_id, point_id, title 
        FROM knowledge_contents 
        WHERE status=1
    """)
    rows = cur.fetchall()
    cur.close()
    conn.close()
    return rows  # [(content_id, point_id, title), ...]

# —— 2. 调用 DeepSeek 生成 Markdown —— #
def generate_markdown(title: str) -> str:
    prompt = f'''请为以下“知识点”生成一段结构化的 Markdown 概述，包含：
1. 一个一级标题：“#{title}”
2. “定义”、“关键点”、“应用” 三个二级小节
3. 每个小节使用 Markdown 列表或段落
4. 总长度约 150–200 字

知识点名称：{title}
'''
    
    # 请替换为您在百度千帆控制台申请的有效 Secret Key
    secret_key = "bce-v3/ALTAK-KRjaKfqkBysadVku5S6Uy/bc401699fd17b1c6785256d74435b546bc0ad4c0"
    # 如果您的账户或接口需要 agent_id，可替换；通常只需 model 即可
    agent_id = "0f1f1ebd-6c61-4354-8d8f-02dd63832274"

    url = "https://qianfan.baidubce.com/v2/chat/completions"
    headers = {
        "Content-Type": "application/json",
        "Authorization": f"Bearer {secret_key}"
    }
    data = {
        # 若不需要 agent_id，可移除此行
        "agent_id": agent_id,
        # 建议使用 deepseek-v3 或其他已开通的模型
        "model": "deepseek-v3",
        "messages": [
            {"role": "system", "content": "你是数据结构课程的助教。"},
            {"role": "user", "content": prompt}
        ],
        # v2 接口参数
        "max_tokens": 400,
        "temperature": 0.7
    }
    session = requests.Session()
    retries = Retry(total=8, backoff_factor=5, status_forcelist=[429, 500, 502, 503, 504])
    session.mount('https://', HTTPAdapter(max_retries=retries))
    while True:
        try:
            resp = session.post(url, headers=headers, json=data, timeout=60)
            resp.raise_for_status()
            result = resp.json()
            return result.get('result') or result.get('data', {}).get('result', '')
        except requests.exceptions.HTTPError as e:
            if e.response is not None and e.response.status_code == 429:
                print("❌ 429限流，自动指数退避重试…")
                time.sleep(10)
                continue
            else:
                raise
        except Exception as e:
            print(f"❌ 处理失败：{e}")
            raise

# —— 3. 写回数据库 —— #
def update_content(content_id: int, md: str):
    conn = pymysql.connect(**DB_CONFIG)
    cur = conn.cursor()
    cur.execute(
        """
        UPDATE knowledge_contents 
        SET content=%s, update_time=NOW() 
        WHERE content_id=%s
        """, (md, content_id)
    )
    conn.commit()
    cur.close()
    conn.close()

# —— 4. 主流程 —— #
def main():
    items = fetch_placeholders()
    print(f"共获取到 {len(items)} 条待处理数据")
    for content_id, point_id, title in items:
        print(f"🔄 生成 “{title}” 的 Markdown 概述…")
        retry = 0
        while True:
            try:
                md = generate_markdown(title)
                update_content(content_id, md)
                print(f"✅ point_id={point_id} 更新完成。\n")
                break
            except requests.exceptions.HTTPError as e:
                if e.response is not None and e.response.status_code == 429:
                    wait = min(120, 10 * (2 ** retry))  # 最长等120秒
                    print(f"❌ 429限流，等待{wait}秒后重试…")
                    time.sleep(wait)
                    retry += 1
                else:
                    print(f"❌ 处理失败 content_id={content_id}：{e}")
                    break
            except Exception as e:
                print(f"❌ 处理失败 content_id={content_id}：{e}")
                break
        time.sleep(5)  # 正常请求间隔5秒，进一步降低QPS

    print("全部更新完毕。")

if __name__ == "__main__":
    main()
